#include "palmdll_yjy.h"

extern int g_SearchStart;
/*
input: color image
output: palm segment result
 */
int palm_segment(const cv::Mat &img, cv::Mat &result)
{
    auto debug = [](const cv::Mat &img) -> void {
        cv::imshow("segment result", img);
        //cv::waitKey(0);
    };
    auto segment_1 = [](const cv::Mat &img, cv::Mat &result) -> int {
        cv::Mat img_gray;
        cvtColor(img, img_gray, CV_BGR2GRAY);
        cv::threshold(img_gray, result, 28, 255, CV_THRESH_BINARY);
        cv::dilate(result, result, cv::Mat(), cv::Point2d(-1, -1), 4);
        cv::erode(result, result, cv::Mat(), cv::Point2d(-1, -1), 4);
        return 1;
    };
    auto segment_2 = [](const cv::Mat &img, cv::Mat &result) -> int {
        cv::Mat img_gray, mask, bgMod, fgMod;
        cv::Rect rect;
        cvtColor(img, img_gray, CV_BGR2GRAY);
        cv::threshold(img_gray, result, 28, 255, CV_THRESH_BINARY);
        result.copyTo(mask);
        for (auto it = mask.begin<uchar>(); it != mask.end<uchar>(); ++it)
        {
            if (*it == 255)
            {
                *it = GC_PR_FGD;
            }
        }
        cv::grabCut(img, mask, rect, bgMod, fgMod, 1, GC_INIT_WITH_MASK);
        g_SearchStart = rect.y;
        std::cout << "g_SearchStart=" << rect.y << std::endl;
        return 1;
    };

    int flag = segment_2(img, result);
    //debug
    debug(result);
    return flag;
}

/*
input: color image
output: coordinates of 3 key points,(yet we don't care about middle-rings key point)
 */
int detect_fincon(cv::Mat &img, int result[6])
{
    cv::Mat segment_result, img_gray;
    cvtColor(img, img_gray, CV_BGR2GRAY);
    palm_segment(img, segment_result);
    //-------------------------------------

    IplImage *imgInput = new IplImage(img_gray);
    IplImage *imgTh = new IplImage(segment_result);
    IplImage *imgPalm = cvCreateImage(cvSize(320, 240), 8, 1);   //标准手掌图像
    IplImage *imgBinary = cvCreateImage(cvSize(320, 240), 8, 1); //二值化手掌区域
    cvResize(imgInput, imgPalm);
    cvResize(imgTh, imgBinary);

    IplImage *imgPalmArea = myGetClearPalmArea(imgBinary); //最终的手掌区域
    IplImage *roi = cvCreateImage(cvSize(128, 128), 8, 1); //roi 图像

    uchar *palmData = (uchar *)imgPalm->imageData;   //获得手掌图像数据
    uchar *thData = (uchar *)imgPalmArea->imageData; //
    uchar *roiData = (uchar *)roi->imageData;        //

    int Sx[4], Sy[4]; //ROI坐标

    int ret = Lnpreprocessing(palmData, thData, roiData, Sx, Sy); //图像预处理

    if (!ret) //出错返回
    {
        cout << "preprocessing error!" << endl;
        return 0;
    }

    printf("The input image has beed resized to320x240\n up :(x,y): %d, %d \ndown:(x,y): %d, %d\n", holeList[0][lastP1Index][0], holeList[0][lastP1Index][1], holeList[1][lastP2Index][0], holeList[1][lastP2Index][1]);

    //finger roots [x1,y1,x2,y2,x3,y3]
    result[0] = holeList[0][lastP1Index][0];
    result[1] = holeList[0][lastP1Index][1];
    result[2] = 0;
    result[3] = 0; //we don't care about middle-rings finger root
    result[4] = holeList[1][lastP2Index][0];
    result[5] = holeList[1][lastP2Index][1];

    const double scale_factor = img.cols / 320.0;
    for (int i = 0; i < 6; i++)
    {
        result[i] *= scale_factor;
    }

    return 1;
}